<!--
 @description select选择
 @fileName index.vue
 @author zengqiongying
 @created 2023-04-20 10:07:47
-->
<template>
  <Popup
    v-model="popShow"
    position="bottom"
    :title="title"
    :clear="clear"
    :show-cancel-button="false"
    @confirm="onSubmit"
    @clear="onClear"
  >
    <div class="select-list-pop" :style="heightStyle">
      <Scroll vertical height="100%">
        <div v-for="(item, i) in list" :key="i" class="option" @click="onClick(item)">
          <span class="name">{{ labelSet(item) }}</span>
          <span class="icon" :class="{ checked: selVal.includes(item[valueName].toString()) }"></span>
        </div>
      </Scroll>
    </div>
  </Popup>
</template>

<script lang="ts">
  import { reactive, toRefs, computed, watch } from 'vue'
  import { Toast } from 'qmp-component'
  import Popup from '@/components/Popup/index.vue'
  import Scroll from '@/components/Scroll/index.vue'
  interface datasModle {
    selVal: any[]
  }
  export default {
    name: 'PopSelect',
    components: { Popup, Scroll },
    props: {
      show: {
        type: Boolean,
        default: false
      },
      title: {
        type: String,
        default: ''
      },
      list: {
        type: Array,
        default: () => []
      },
      modelValue: {
        type: [String, Number, Array],
        default: ''
      }, // 选中的值
      label: {
        type: String,
        default: ''
      }, // 选中的值的名称
      valueName: {
        // 选项值键名
        type: String,
        default: 'id'
      },
      labelName: {
        // 选项名称键名
        type: String,
        default: ''
      },
      labelFunc: {
        // 选项名称自定义回调方法
        type: Function,
        default: null
      },
      height: {
        type: [Number, String],
        default: ''
      },
      multiple: {
        // 是否多选
        type: Boolean,
        default: false
      },
      clear: {
        // 是否允许清空
        type: Boolean,
        default: false
      }
    },
    setup(props: any, ctx: any) {
      const datas = reactive<datasModle>({
        selVal: []
      })
      const popShow = computed({
        set(val) {
          ctx.emit('update:show', val)
        },
        get() {
          return props.show
        }
      })
      const heightStyle = computed(() => {
        if (props.height) {
          const height = typeof props.height === 'number' ? `${props.height}px` : props.height
          return {
            height
          }
        }
        return {}
      })
      watch(
        () => props.modelValue,
        (val) => {
          datas.selVal = []
          if (props.multiple) {
            if (val && val instanceof Array) {
              val.forEach((e) => {
                if (!(e === null || e === undefined || e === '')) {
                  datas.selVal.push(e.toString())
                }
              })
            }
          } else {
            if (!(val === null || val === undefined || val === '')) {
              datas.selVal.push(val.toString())
            }
          }
          const names: string[] = []
          if (datas.selVal && datas.selVal.length > 0) {
            props.list.forEach((v: any) => {
              const val = v[props.valueName].toString()
              if (datas.selVal.includes(val)) {
                names.push(v[props.labelName])
              }
            })
          }
          ctx.emit('update:label', names.join(','))
        },
        {
          deep: true,
          immediate: true
        }
      )
      const onClick = (data: any) => {
        const val = data[props.valueName].toString()
        if (!props.multiple) {
          datas.selVal = [val]
          return
        }
        const index = datas.selVal.findIndex((v) => v === val)
        if (index === -1) {
          datas.selVal.push(val)
        } else {
          datas.selVal.splice(index, 1)
        }
      }
      const onSubmit = () => {
        if (!datas.selVal || datas.selVal.length === 0) {
          Toast('请选择')
          return
        }
        const selArr = props.list.filter((v: any) => {
          const val = v[props.valueName].toString()
          return datas.selVal.includes(val)
        })
        const names = selArr.map((v: any) => {
          return v[props.labelName]
        })
        ctx.emit('update:modelValue', props.multiple ? datas.selVal : datas.selVal[0])
        ctx.emit('update:label', names.join(','))
        ctx.emit('selectChange', props.multiple ? selArr : selArr[0])
        popShow.value = false
      }
      const onClear = () => {
        datas.selVal = []
        ctx.emit('update:modelValue', props.multiple ? [] : '')
        ctx.emit('update:label', '')
        ctx.emit('selectChange', '')
        popShow.value = false
      }
      const labelSet = (item: any) => {
        if (props.labelFunc && props.labelFunc instanceof Function) {
          return props.labelFunc(item)
        } else {
          return item[props.labelName]
        }
      }
      return {
        ...toRefs(datas),
        popShow,
        heightStyle,
        onClear,
        labelSet,
        onClick,
        onSubmit
      }
    }
  }
</script>
<style lang="less" scoped>
  .select-list-pop {
    padding: 0 16px;
    border-radius: 8px;
    background: var(--bg-global-weaker);
    overflow: hidden;
    height: 40vh;
    position: relative;
    .option {
      position: relative;
      height: 54px;
      display: flex;
      justify-content: space-between;
      align-items: center;
      &::after {
        position: absolute;
        box-sizing: border-box;
        content: ' ';
        pointer-events: none;
        left: 0;
        right: 0;
        bottom: 0;
        border-bottom: 1px solid var(--divisionline-weak);
        -webkit-transform: scaleY(0.5);
        transform: scaleY(0.5);
      }
      &:last-child::after {
        border-bottom: 0;
      }
    }
    .name {
      font-size: 17px;
      color: #3c4458;
    }
    .icon {
      width: 20px;
      height: 14px;
      margin-left: 10px;
      &.checked {
        background: url(~@/assets/images/icon-yes.png);
        background-size: 20px 14px;
      }
    }
  }
</style>
